<?php
namespace app\admin\controller;
use think\Db;
class Tuiwx extends Base {
// 定义配置项
    private $config=array(
        'APPID'              => 'wxbc251630849b1291', // 微信支付APPID.
        'MCHID'              => '1510804091', // 微信支付MCHID 商户收款账号  1556016481
        'KEY'                => 'dhgyQ67PG1xIveAiav5hCZySLV13ESW4', // 微信支付KEY  uniNCx3NaBq8yt7pFh4m1gY1dIqsALAy
        'APPSECRET'          => '159515acfedfe5cb0971eaeb7ad248ed', // 公众帐号secert (公众号支付专用)

    );
    //----------------------------提现 S-----------------------------------
    /**
     * app支付统一退款
     */
    public function refundWx($payInfo,$refundNo){
        //transaction_id,money,number
//    public function refundWx(){
        header("content-type:text/html;charset=utf-8");
        $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        $data["appid"] 		  = $this->config['APPID'];//微信开放平台审核通过的应用APPID
        $data["mch_id"] 	  = $this->config['MCHID'];//商户号
        $data["nonce_str"] 	  = $this->getRandChar(32);//随机字符串
        $data["out_refund_no"]   = $refundNo; //退款单号，每次不同，每次退
        $data["refund_fee"] = $payInfo['money']*100;
        $data["total_fee"]  = $payInfo['total_price']*100;//总金额按乘以100进行计算
        $data["out_trade_no"] = $payInfo['number'];
        $data["refund_fee_type"] = "CNY";
        $data["refund_account"] = "REFUND_SOURCE_UNSETTLED_FUNDS";
        $sign=$this->getSignRefund($data,$this->config['KEY']);
        $data['sign']=$sign;
        $xml=$this->toXml($data);
        $response 	= $this->postXmlCurl($xml, $url,'',true,'/cert/apiclient_cert.pem','/cert/apiclient_key.pem');
        $responseArr=$this->toArray($response);
        if(!is_array($responseArr) || count($responseArr)<=0){
            $return['msg'] = '网络请求繁忙';
            $return['status'] = 0;
        }else if($responseArr['return_code'] == 'FAIL'){
            $return['msg'] = $responseArr['return_msg'];
            $return['status'] = 0;
        }else if($responseArr['result_code'] == 'FAIL'){
            $return['msg'] = $responseArr['err_code_des'];
            $return['status'] = 0;
        }else{
            $chaxun = $this->refundWxChaxun($refundNo);
            if($chaxun['status'] == 200){
                //二次签名
                $return['text'] = $responseArr;
//			直接返回
                $return['status'] = 200;
            }else{
                $return['msg'] = $chaxun['msg'];
                $return['status'] = 0;
            }

        }
        return $return;
    }
    /**
     * app支付统一退款查询：微信退款就算余额不足也会返回成功，所以要先查询判断
     */
    public function refundWxChaxun($refundNo){
//    public function refundWxChaxun(){
        header("content-type:text/html;charset=utf-8");
        $url = "https://api.mch.weixin.qq.com/pay/refundquery";
        $data["appid"] 		  = $this->config['APPID'];//微信开放平台审核通过的应用APPID
        $data["mch_id"] 	  = $this->config['MCHID'];//商户号
        $data["nonce_str"] 	  = $this->getRandChar(32);//随机字符串
        $data["out_refund_no"]   = $refundNo;
        $sign=$this->getSignRefund($data,$this->config['KEY']);
        $data['sign']=$sign;
        $xml=$this->toXml($data);
        $response 	= $this->postXmlCurl($xml, $url,'',false,'','');
        $responseArr = $this->toArray($response);
        if(!is_array($responseArr) || count($responseArr)<=0){
            $return['msg'] = '网络请求繁忙';
            $return['status'] = 0;
        }else if($responseArr['return_code'] == 'FAIL'){
            $return['msg'] = $responseArr['return_msg'];
            $return['status'] = 0;
        }else{
            if($responseArr['result_code'] == 'SUCCESS'){
                $return['msg'] = 'ok';
                $return['status'] = 200;
            }else{
                if($responseArr['err_code_des'] == 'not exist'){
                    $responseArr['err_code_des'] = '商户平台余额不足，请联系管理员充值';
                }
                $return['msg'] = $responseArr['err_code_des'];
                $return['status'] = 0;
            }
        }
        return $return;
    }

//获取指定长度的随机字符串
    function getRandChar($length){
        $str = null;
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol)-1;

        for($i=0;$i<$length;$i++){
            $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
        }

        return $str;
    }
    function getSignRefund($obj, $api_key)
    {
        foreach ($obj as $k => $v)
        {
            $Parameters[strtolower($k)] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);

        //签名步骤二：在string后加入KEY
        $String = $String."&key=".$api_key;
        //签名步骤三：MD5加密
        $result = strtoupper(md5($String));
//        $result = hash_hmac("sha256",stringSignTemp,key);
        return $result;
    }
    function formatBizQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v)
        {
            if($urlencode)
            {
                $v = urlencode($v);
            }
            $buff .= strtolower($k) . "=" . $v . "&";
        }
        $reqPar = '';
        if (strlen($buff) > 0)
        {
            $reqPar = substr($buff, 0, strlen($buff)-1);
        }
        return $reqPar;
    }
    function postXmlCurl($xml, $url, $second=30, $useCert=false, $sslcert_path, $sslkey_path)
    {
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch,CURLOPT_URL, $url);

        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);

        if($useCert == true){
            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
            curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
//            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
//			curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,1);//严格校验
            //设置证书
            $path = $_SERVER['DOCUMENT_ROOT'];
            curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
            curl_setopt($ch,CURLOPT_SSLCERT, $path.$sslcert_path);
            curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
            curl_setopt($ch,CURLOPT_SSLKEY, $path.$sslkey_path);
//            curl_setopt($ch,CURLOPT_CAINFO, __DIR__.'/cert/rootca.pem');
        }
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if($data){
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            return false;
        }
    }
    /**
     * 输出xml字符
     * @throws WxPayException
     **/
    public function toXml($data){
        //var_dump($data);
        if(!is_array($data) || count($data) <= 0){
            //throw new WxPayException("数组数据异常！");
        }
        $xml = "<xml>";
        foreach ($data as $key=>$val){
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
    /**
     * 将xml转为array
     * @param  string $xml xml字符串
     * @return array       转换得到的数组
     */
    public function toArray($xml){
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $result;
    }

}